﻿#pragma once
#include "XyNet/Crypto/CryptoPP.h"

namespace XyNet
{
	/// ECC加解密器
	/// 使用方法：首先生成解密器，然后用解密器生成加密器。
	/// 发送加密器的公钥给对方，对方用公钥生成加密器后加密消息。
	/// 对方传回加密的消息，用解密器解开消息
	class XYNET_API Ecc
	{
	public:
		/// 密钥类型
		enum KeyType
		{
			EccDefault = 0,	// 默认Aes128
			Ecc160 = 160,
			Ecc192 = 192,
			Ecc224 = 224,
			Ecc256 = 256,
			Ecc320 = 320,
			Ecc384 = 384,
			Ecc512 = 512
		};

		class Encryptor;

		/// 解密器
		class XYNET_API Decryptor : noncopyable
		{
			friend class Encryptor;

		public:
			/// bit只能取160,192,224,256,320,384,512，根据bit生成随机key
			Decryptor(KeyType keyType = EccDefault);
			/// 手动指定私有密钥
			Decryptor(const Bytes& key);

			/// 获取私有密钥
			Bytes getPrivateKey() const;
			/// 设置私有密钥
			void setPrivateKey(const Bytes& key);
			/// 设置随机密钥
			void setRandomKey(KeyType keyType = EccDefault);

			/// 解密
			Bytes decrypt(const Bytes& input);

		private:
			/// 解密器
			CryptoPP::ECIES<CryptoPP::ECP>::Decryptor _decryptor;
		};

		/// 加密器
		class XYNET_API Encryptor : noncopyable
		{
		public:
			/// 未定义公共密钥
			Encryptor();
			/// 由解密器生成加密器
			Encryptor(const Decryptor& decryptor);
			/// 手动指定公共密钥
			Encryptor(const Bytes& key);

			/// 获取公共密钥
			Bytes getPublicKey() const;
			/// 设置公共密钥
			void setPublicKey(const Bytes& key);
			/// 从解密器设置密钥
			void setKey(const Decryptor& decryptor);

			/// 加密
			Bytes encrypt(const Bytes& input);

		private:
			/// 加密器
			CryptoPP::ECIES<CryptoPP::ECP>::Encryptor _encryptor;
		};

	private:
		/// 获取默认密钥类型
		static KeyType getDefaultKeyType();
		/// 设置默认密钥类型
		static void setDefaultKeyType(KeyType keyType);

		/// 默认密钥类型
		static KeyType _defaultKeyType;
	};
}